/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gra.Renderer;

import gra.GUI.GUI;
import gra.mechanika.Obiekty.Statek;
import gra.Gra;
import gra.Stoper;
import gra.mechanika.Mechanika;
import java.awt.Font;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.*;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.UnicodeFont;

/**
 *
 * @author Grog
 */
public class Renderer {

    static KameraFPP kamera;
    private long lastFrame = 0;
    int dx = 1;
    int dy = 1;
    int dz = 1;
    public int delta = 0;
    public List<Statek> ListaOBJ;
    private static UnicodeFont font;
    public static FloatBuffer perspectiveProjectionMatrix = reserveData(16);
    public static FloatBuffer orthograficProjectionMatrix = reserveData(16);
    public GUI gui;
    /**
     * The minimal distance from the camera where objects are rendered.
     */
    public static float zNear = 0.001f;
    /**
     * The maximal distance from the camera where objects are rendered.
     */
    public static float zFar = 100f;
    /**
     * Defines the field of view.
     */
    public static int fov = 68;
    Mechanika mechanika;

    public Renderer() {


        try {

            Display.setDisplayMode(new DisplayMode(640, 480));
            Display.setTitle("Yo");
            Display.create();
            Display.setVSyncEnabled(true);

            //Ustawienie kamery
            ustawKamere();


            //gui = new GUI(this);
            //ustawianie swiatel
            setUpLighting();
           
            /*
            glEnable(GL11.GL_LIGHTING);
            glEnable(GL11.GL_LIGHT0);
            
            glEnable(GL_CULL_FACE);
            glDisable(GL_DEPTH_TEST);
            glEnable(GL_DEPTH_TEST);
            glDisable(GL_CULL_FACE);
            glEnable(GL_TEXTURE_2D);
            */

        //    glBindTexture(GL_TEXTURE_2D, 0);







        } catch (LWJGLException ex) {
            Logger.getLogger(Gra.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Renderer odpalony");
        ListaOBJ = new ArrayList<>();
        lastFrame = getTime();






    }

    public void ustawMechanike(Mechanika m) {
        this.mechanika = m;
    }

    private long getTime() {
        return (Sys.getTime() * 1000) / Sys.getTimerResolution();
    }

    //petla renderera
    public void wyswietl() throws IOException {

        delta = getDelta();
        //obsługa kamery
        kamera.obslugaKamery(delta);
        //czyszczenie obrazu
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //TODO zaladuj listę wszystkich obiektów do wyswietlenia i wyswietl je         
        
        
        glTranslatef(0, 0, -3);
              
        
      /*
            glBegin(GL_TRIANGLES);
            glVertex3d(0, 0, 0);
            glTexCoord2f(0, 1);
            
            glVertex3d(3, 0, 0);
           glTexCoord2f(0, 0);
            
            glVertex3d(0, 3, 0);
            
            glEnd();
         */      
                
        
        
        
        // gui.wyswietlGUI();
        if (!ListaOBJ.isEmpty()) {
           
            for (int index = 0; index < ListaOBJ.size(); index++) {

                glPushMatrix();
                
                ListaOBJ.get(index).wyswietl_Obj();
                
                // zielona kreska pod statkiem 
                glTranslatef(0, -1, 0);  
                GL11.glColor3f(0.0f, 1.0f, 0.0f);
                glBegin(GL_LINES);
                glVertex3d(0, 0, 0);
                glVertex3d(0, 0, 1);
                glEnd();
 
                glPopMatrix();
                
                
            }
            
           
            
            
            
        }//koniec dodawania

        

                
        glLight(GL_LIGHT0, GL_POSITION, asFloatBuffer(new float[]{0f,10f,5f,1f}));
        //wywołuje metodę update
        update();
    }

    
    Stoper sFps=new Stoper();
    
    public void updateFPS() {
  
            if (sFps.czyMinelo(1)) {
                Display.setTitle("FPS: " + 1000 / delta);
            }
        

       

    }

    public void update() {



        Display.update();
        Display.sync(60);

        if (Display.isCloseRequested()) {
            Gra.posprzataj();
        }

        updateFPS();
    }

    private int getDelta() {
        long currentTime = getTime();
        delta = (int) (currentTime - lastFrame);
        lastFrame = getTime();

        return delta;
    }

    public void zakoncz() {
        Display.destroy();
    }

    public void fullscreen() {
    }

    public static void ustawKamere() {
        kamera = new KameraFPP((float) Display.getWidth() / (float) Display.getHeight(), 0.0f, 0.0f, 0.0f);
        kamera.setFov(70);
        kamera.setSzybkosc(120f);
        kamera.applyProjectionMatrix();


       // glGetFloat(GL_PROJECTION_MATRIX, perspectiveProjectionMatrix);
       // glMatrixMode(GL_PROJECTION);
       // glLoadIdentity();
       // glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);
       // glGetFloat(GL_PROJECTION_MATRIX, orthograficProjectionMatrix);
       // glLoadMatrix(perspectiveProjectionMatrix);
       // glMatrixMode(GL_MODELVIEW_MATRIX);


    }

    private static void setUpLighting() {
        glShadeModel(GL_SMOOTH);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_TEXTURE_2D);
       // glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        
        glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE, asFloatBuffer(new float[]{0.5f, 0.5f, 0.5f, 1f}));
        glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS, 0);
        
        
        glEnable(GL_LIGHT0);
        glLightModel(GL_LIGHT_MODEL_AMBIENT, asFloatBuffer(new float[]{0.5f, 0.5f, 0.5f, 1f}));
        glLight(GL_LIGHT0, GL_POSITION,
                asFloatBuffer(new float[]{1.5f, 1.5f, 1.5f, 1}));
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
        glEnable(GL_COLOR_MATERIAL);
        glColorMaterial(GL_FRONT, GL_DIFFUSE);
        
        
       
    }
    
    
    public void wlaczTekstury(boolean x){   
        if(x){          
        glEnable(GL_TEXTURE_2D);     
        System.out.println("Tekstury Włączone");
        } 
        if(!x){
        glDisable(GL_TEXTURE_2D);
         System.out.println("Tekstury Wyłączone");
        }
        
    }

    

    public void zmianaSzybkosciKam(float zmiana) {
        kamera.setSzybkosc(kamera.getSzybkosc() + zmiana);
        System.out.println(kamera.getSzybkosc());
    }

    public void resetujKamere() {


        kamera.pozycja.set(0, 0, 0);
        kamera.rotacja.set(0, 0, 0);
    }

    public void ustawFont() {
        java.awt.Font awtFont = new Font("Times New Roman", java.awt.Font.BOLD, 18);
        font = new UnicodeFont(awtFont);
        font.addAsciiGlyphs();
        try {
            font.loadGlyphs();
        } catch (SlickException ex) {
            ex.printStackTrace();

        }
    }

    private static FloatBuffer reserveData(int size) {
        FloatBuffer data = BufferUtils.createFloatBuffer(size);
        return data;
    }
    
    private static FloatBuffer asFloatBuffer(float... values) {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(values.length);
        buffer.put(values);
        buffer.flip();
        return buffer;
    }
}
